package io.gitee.sfch.chunmi.code.generator.service.impl;


import io.gitee.sfch.chunmi.code.generator.service.TemplateEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.tools.ToolManager;
import org.apache.velocity.tools.config.EasyFactoryConfiguration;
import org.apache.velocity.tools.generic.CollectionTool;
import org.apache.velocity.tools.generic.ComparisonDateTool;
import org.apache.velocity.tools.generic.DisplayTool;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.JsonTool;
import org.apache.velocity.tools.generic.LinkTool;
import org.apache.velocity.tools.generic.LoopTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.apache.velocity.tools.generic.XmlTool;
import org.springframework.stereotype.Service;

import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;

/**
 * Velocity模版引擎
 */
@Service
public class VelocityTemplateEngine implements TemplateEngine {

    private final VelocityEngine velocityEngine;
    private final ToolManager toolManager;

    public VelocityTemplateEngine() {
        Properties prop = new Properties();
        prop.put(RuntimeConstants.RESOURCE_LOADER, "classpath");
        prop.put("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
        velocityEngine = new VelocityEngine(prop);
        velocityEngine.init();

        toolManager = new ToolManager();
        EasyFactoryConfiguration config = new EasyFactoryConfiguration();
        config.toolbox("application")
                .tool(ComparisonDateTool.class)
                .tool(MathTool.class)
                .tool(NumberTool.class)
                .tool(DisplayTool.class)
                .tool(EscapeTool.class)
                .tool(CollectionTool.class)
                .tool(XmlTool.class)
                .tool(JsonTool.class);
        config.toolbox("request")
                .tool(LinkTool.class)
                .tool(LoopTool.class);
        toolManager.configure(config);
    }

    @Override
    public String render(String templateName, Map<String, Object> model) {
        Context context = new VelocityContext(model, toolManager.createContext());
        Template template = velocityEngine.getTemplate("velocity/" + templateName + ".vm",
                StandardCharsets.UTF_8.name());
        StringWriter stringWriter = new StringWriter();
        template.merge(context, stringWriter);

        return stringWriter.toString();
    }
}
